package com.netx.generics.basic;
import java.io.PrintStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import com.netx.generics.io.Location;
import com.netx.generics.time.Moment;

import java.util.Iterator;


public abstract class Tester {

	protected final PrintStream out;
	protected final PrintStream err;
	private final String _base = "C:/Shared/04.Dev/04.Test";
	
	protected Tester() {
		out = System.out;
		err = System.err;
	}
	
	protected void printArray(Object[] array) {
		for(int i=0; i<array.length; i++) {
			out.println("["+i+"]: "+array[i]);
		}
	}
	
	protected void printIterator(Iterator<?> it) {
		for(int i=0; it.hasNext(); i++) {
			out.println("["+i+"]: "+it.next());
		}
	}

	protected Location getTestLocation() {
		return new Location(_base);
	}
	
	protected Location getTestLocationForPackage() {
		return new Location(_base+"/"+getClass().getPackage().getName().replaceAll("[.]", "/"));
	}

	public enum FORMAT {MOMENT, DATE, TIME}

	protected void showObjectProperty(Object obj, String methodName) {
		showObjectProperty(obj, methodName, null);
	}
	
	protected void showObjectProperty(Object obj, String methodName, FORMAT format) {
		Checker.checkNull(obj, "obj");
		Checker.checkEmpty(methodName, "methodName");
		try {
			Method m = obj.getClass().getMethod(methodName, new Class[0]);
			if(m.getReturnType() == Void.class) {
				throw new IllegalArgumentException("method '"+methodName+"' has void return type");
			}
			Object result = m.invoke(obj);
			out.print(methodName);
			out.print("(): ");
			if(format != null) {
				Moment moment = new Moment((Long)result);
				// Dont't format if millis==0:
				if(moment.getTimeInMilliseconds() != 0) {
					if(format == FORMAT.MOMENT) {
						result = moment;
					}
					else if(format == FORMAT.DATE) {
						result = moment.getDate();
					}
					else if(format == FORMAT.TIME) {
						result = moment.getTime();
					}
				}
			}
			out.println(result);
		}
		catch(NoSuchMethodException nsme) {
			throw new IllegalArgumentException(methodName+"(): method does not exist");
		}
		catch(IllegalAccessException iae) {
			throw new IllegalArgumentException(methodName+"(): method is not accessible");
		}
		catch(InvocationTargetException ite) {
			throw new IllegalUsageException(methodName+"(): invoke threw exception: "+ite, ite);
		}
	}
}
